package cc.rengu.igas.bomp.core.service.trans;

import cc.rengu.igas.bomp.common.constant.TableNameConstant;
import cc.rengu.igas.bomp.common.dao.*;
import cc.rengu.igas.bomp.common.dao.impl.*;
import cc.rengu.igas.bomp.common.entity.*;
import cc.rengu.igas.bomp.common.enums.ProdAuthCtrlEnum;
import cc.rengu.igas.bomp.common.enums.QueryBizTypeEnum;
import cc.rengu.igas.bomp.common.enums.RespCodeEnum;
import cc.rengu.igas.bomp.common.util.InitParamUtil;
import cc.rengu.igas.bomp.core.service.base.ManageService;
import cc.rengu.igas.bomp.facade.bean.MchntAuthCtrlInfoBean;
import cc.rengu.igas.bomp.facade.bean.MchntFeeInfoBean;
import cc.rengu.igas.bomp.facade.bean.MchntStageInfoBean;
import cc.rengu.igas.bomp.facade.request.MchntProdInfoQueryRequest;
import cc.rengu.igas.bomp.facade.response.MchntProdInfoQueryResponse;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.utility.util.BeanUtil;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.StringUtil;
import com.alibaba.fastjson.JSON;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 商户产品信息查询
 * Created by 赵奎伍
 */
public class MchntProdInfoQueryService extends ManageService {
    @Override
    protected Object bizBeforeCust() throws Exception {
        MchntProdInfoQueryRequest mchntProdInfoQueryRequest = new MchntProdInfoQueryRequest();
        ConvertUtil.convertOutput(mchntProdInfoQueryRequest);
        return mchntProdInfoQueryRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        MchntProdInfoQueryRequest mchntProdInfoQueryRequest = (MchntProdInfoQueryRequest) request;
        MchntProdInfoQueryResponse mchntProdInfoQueryResponse = new MchntProdInfoQueryResponse();
        BizResponse<MchntProdInfoQueryResponse> bizResponse = new BizResponse<>();
        bizResponse.setRspSysId(AppParamConstant.IGAS);
        BeanUtil.beanCopy(mchntProdInfoQueryRequest, mchntProdInfoQueryResponse);

        String instId = mchntProdInfoQueryRequest.getHeader().getInstId();
        String mchntNo = mchntProdInfoQueryRequest.getMchntNo();
        String baseProdCode = mchntProdInfoQueryRequest.getBaseProdCode();
        String prodCode = mchntProdInfoQueryRequest.getProdCode();

        String bizType = mchntProdInfoQueryRequest.getHeader().getBizType();
        if (StringUtil.isEmptyOrNull(bizType)) {
            rglog.error("bizType<{}>为NULL!,无法查询信息", bizType);
            bizResponse.setRespCode(RespCodeEnum.PARAM_ERROR.getRespCode());
            bizResponse.setRespDesc(RespCodeEnum.PARAM_ERROR.getRespDesc());
            bizResponse.setResult(mchntProdInfoQueryResponse);
            return bizResponse;
        }

        if (QueryBizTypeEnum.QUERY_TEMPORARY_TABLE.getType().equals(bizType)) {
            /* 查询临时表数据 */
            BizTmpMapper bizTmpMapper = new BizTmpMapperImpl();
            //查询商户产品信息表
            List<BizTmp> prodBizTmpList = bizTmpMapper.selectBizTmpByMchntNo(instId, mchntNo, TableNameConstant.T_B_MCHNT_PROD_INFO);
            if (!CollectionUtils.isEmpty(prodBizTmpList)) {

                for (BizTmp bizTmp : prodBizTmpList) {
                    String prodInfoJson = InitParamUtil.getJsonString(bizTmp);

                    MchntProdInfo mchntProdInfo = JSON.parseObject(prodInfoJson, MchntProdInfo.class);
                    if (baseProdCode.equals(mchntProdInfo.getBaseProdCode())) {
                        BeanUtil.beanCopy(mchntProdInfo, mchntProdInfoQueryResponse);
                        mchntProdInfoQueryResponse.setAlipayChannelId(mchntProdInfo.getAlipayChannelId());
                        //名字在何处取值
                        mchntProdInfoQueryResponse.setAlipayChannelName(mchntProdInfo.getAlipayChannelId());
                        mchntProdInfoQueryResponse.setWechatChannelId(mchntProdInfo.getWechatChannelId());
                        mchntProdInfoQueryResponse.setWechatChannelName(mchntProdInfo.getWechatChannelId());
                    }
                }

                List<BizTmp> baseBizTmp = bizTmpMapper.selectBizTmpByMchntNo(instId, mchntNo, TableNameConstant.T_B_MCHNT_BASE_INFO);
                if (!CollectionUtils.isEmpty(baseBizTmp)) {
                    BizTmp bizTmp = baseBizTmp.get(0);
                    String mchntBaseInfoString = InitParamUtil.getJsonString(bizTmp);
                    MchntBaseInfo mchntBaseInfo = JSON.parseObject(mchntBaseInfoString, MchntBaseInfo.class);
                    mchntProdInfoQueryResponse.setMchntSignType(mchntBaseInfo.getMchntSignType());
                }

                //商户分期信息表
                List<BizTmp> stageBizTmpList = bizTmpMapper.selectBizTmpByMchntNo(instId, mchntNo, TableNameConstant.T_B_MCHNT_STAGE_INFO);
                if (!CollectionUtils.isEmpty(stageBizTmpList)) {
                    List<MchntStageInfo> mchntStageInfoList = new ArrayList<>();
                    for (BizTmp bizTmp : stageBizTmpList) {
                        String stageInfoJson = InitParamUtil.getJsonString(bizTmp);

                        MchntStageInfo mchntStageInfo = JSON.parseObject(stageInfoJson, MchntStageInfo.class);
                        if (baseProdCode.equals(mchntStageInfo.getBaseProdCode())) {
                            mchntStageInfoList.add(mchntStageInfo);
                        }
                    }
                    /* 按照创建时间降序排序 */
                    mchntStageInfoList = mchntStageInfoList.stream().sorted(Comparator.comparing(MchntStageInfo::getCreateTime)).collect(Collectors.toList());
                    Collections.reverse(mchntStageInfoList);

                    List<MchntStageInfoBean> mchntStageInfoBeans = new ArrayList<>();
                    mchntStageInfoList.forEach(item -> convStageInfo(item, mchntStageInfoBeans));
                    /* 查询结果赋值 */
                    mchntProdInfoQueryResponse.setMchntStageInfoList(mchntStageInfoBeans);
                }

                //商户费率信息表
                List<BizTmp> feeBizTmpList = bizTmpMapper.selectBizTmpByMchntNo(instId, mchntNo, TableNameConstant.T_B_MCHNT_FEE_INFO);
                if (!CollectionUtils.isEmpty(feeBizTmpList)) {
                    List<MchntFeeInfo> mchntFeeInfoList = new ArrayList<>();
                    for (BizTmp bizTmp : feeBizTmpList) {
                        String feeInfoJson = InitParamUtil.getJsonString(bizTmp);

                        MchntFeeInfo mchntFeeInfo = JSON.parseObject(feeInfoJson, MchntFeeInfo.class);
                        if (baseProdCode.equals(mchntFeeInfo.getBaseProdCode())) {
                            mchntFeeInfoList.add(mchntFeeInfo);
                        }
                    }
                    /* 按照创建时间降序排序 */
                    mchntFeeInfoList = mchntFeeInfoList.stream().sorted(Comparator.comparing(MchntFeeInfo::getCreateTime)).collect(Collectors.toList());
                    Collections.reverse(mchntFeeInfoList);

                    List<MchntFeeInfoBean> mchntFeeInfoBeans = new ArrayList<>();
                    mchntFeeInfoList.forEach(item -> convFeeInfo(item, mchntFeeInfoBeans));
                    /* 查询结果赋值 */
                    mchntProdInfoQueryResponse.setMchntFeeInfoList(mchntFeeInfoBeans);
                }

                List<BizTmp> authBizTmpList = bizTmpMapper.selectBizTmpByMchntNo(instId, mchntNo, TableNameConstant.T_B_MCHNT_AUTH_CTRL);
                if (!CollectionUtils.isEmpty(authBizTmpList)) {
                    List<MchntAuthCtrl> mchntAuthCtrlList = new ArrayList<>();
                    for (BizTmp bizTmp : authBizTmpList) {
                        String authInfoJson = InitParamUtil.getJsonString(bizTmp);

                        MchntAuthCtrl mchntAuthCtrl = JSON.parseObject(authInfoJson, MchntAuthCtrl.class);
                        if (baseProdCode.equals(mchntAuthCtrl.getBizProdCode())) {
                            mchntAuthCtrlList.add(mchntAuthCtrl);
                        }

                    }
                    /* 按照创建时间降序排序 */
                    mchntAuthCtrlList = mchntAuthCtrlList.stream().sorted(Comparator.comparing(MchntAuthCtrl::getCreateTime)).collect(Collectors.toList());
                    Collections.reverse(mchntAuthCtrlList);

                    List<MchntAuthCtrlInfoBean> mchntAuthCtrlInfoBeans = new ArrayList<>();

                    mchntAuthCtrlList.forEach(item -> convAuthCtrlInfo(item, mchntAuthCtrlInfoBeans));
                    /* 查询结果赋值 */
                    mchntProdInfoQueryResponse.setMchntAuthCtrlInfoList(mchntAuthCtrlInfoBeans);
                }

                List<BizTmp> wechatBizList = bizTmpMapper.selectBizTmpByMchntNo(instId, mchntNo, TableNameConstant.T_B_WECHAT_MCHNT_INFO);
                if (!CollectionUtils.isEmpty(wechatBizList)) {
                    String wechatJson = InitParamUtil.getJsonString(wechatBizList.get(0));
                    WechatMchntInfo wechatMchntInfo = JSON.parseObject(wechatJson, WechatMchntInfo.class);
                    mchntProdInfoQueryResponse.setWechatAppid(wechatMchntInfo.getAppId());
                    mchntProdInfoQueryResponse.setWechatAppidKey(wechatMchntInfo.getAppSecretKey());
                    mchntProdInfoQueryResponse.setWechatMiniAppid(wechatMchntInfo.getMiniAppId());
                    mchntProdInfoQueryResponse.setWechatMiniAppidKey(wechatMchntInfo.getMiniSecretKey());
                    mchntProdInfoQueryResponse.setWechatSelfEntryFlag(wechatMchntInfo.getIndependentEntryFlag());
                }

                List<BizTmp> cupsBizList = bizTmpMapper.selectBizTmpByMchntNo(instId, mchntNo, TableNameConstant.T_B_CUPS_MCHNT_INFO);
                if (!CollectionUtils.isEmpty(cupsBizList)) {
                    String cupsJson = InitParamUtil.getJsonString(cupsBizList.get(0));
                    CupsMchntInfo cupsMchntInfo = JSON.parseObject(cupsJson, CupsMchntInfo.class);
                    mchntProdInfoQueryResponse.setCupsChannelMchntNo(cupsMchntInfo.getCupsChannelMchntNo());
                }

                /* 按照接口转换基础产品信息并响应给请求方 */
                bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
                bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
                bizResponse.setResult(mchntProdInfoQueryResponse);
            } else {
                //兼容迁移数据，查询正式表
                rglog.error("商户号<{}>，临时表无商户产品信息!，查询正式表！", mchntProdInfoQueryResponse.getMchntNo());
                getMchntProdInfoFromFormalTable(mchntProdInfoQueryRequest, mchntProdInfoQueryResponse, bizResponse, instId, mchntNo, baseProdCode, prodCode);
            }

        } else {
            //查询正式表
            getMchntProdInfoFromFormalTable(mchntProdInfoQueryRequest, mchntProdInfoQueryResponse, bizResponse, instId, mchntNo, baseProdCode, prodCode);
        }


        return bizResponse;
    }

    private void getMchntProdInfoFromFormalTable(MchntProdInfoQueryRequest mchntProdInfoQueryRequest, MchntProdInfoQueryResponse mchntProdInfoQueryResponse, BizResponse<MchntProdInfoQueryResponse> bizResponse, String instId, String mchntNo, String baseProdCode, String prodCode) throws Exception {
        /* 查询正式表数据 */
        MchntBaseInfoMapper mchntBaseInfoMapper = new MchntBaseInfoMapperImpl();
        MchntBaseInfo mchntBaseInfo = mchntBaseInfoMapper.selectMchntBaseInfoByPrimaryKey(instId, mchntNo);
        if (null != mchntBaseInfo) {
            mchntProdInfoQueryResponse.setMchntSignType(mchntBaseInfo.getMchntSignType());
        }

        // 1. 查询商户产品信息表
        MchntProdInfoMapper mchntProdInfoMapper = new MchntProdInfoMapperImpl();
        MchntProdInfo mchntProdInfo = mchntProdInfoMapper.selectMchntProdInfoByPrimaryKey(instId, mchntNo, baseProdCode);
        if (mchntProdInfo != null) {
            BeanUtil.beanCopy(mchntProdInfo, mchntProdInfoQueryResponse);
            mchntProdInfoQueryResponse.setAlipayChannelId(mchntProdInfo.getAlipayChannelId());
            mchntProdInfoQueryResponse.setAlipayChannelName(mchntProdInfo.getAlipayChannelId());
            mchntProdInfoQueryResponse.setWechatChannelId(mchntProdInfo.getWechatChannelId());
            mchntProdInfoQueryResponse.setWechatChannelName(mchntProdInfo.getWechatChannelId());

            // 2. 商户分期信息表
            MchntStageInfoMapper mchntStageInfoMapper = new MchntStageInfoMapperImpl();
            List<MchntStageInfo> mchntStageInfoList = mchntStageInfoMapper.selectMchntStageInfoByBaseProdCode(instId, mchntNo, baseProdCode, prodCode);
            if (null != mchntStageInfoList && !mchntStageInfoList.isEmpty()) {
                /* 按照创建时间降序排序 */
                mchntStageInfoList = mchntStageInfoList.stream().sorted(Comparator.comparing(MchntStageInfo::getCreateTime)).collect(Collectors.toList());
                Collections.reverse(mchntStageInfoList);

                List<MchntStageInfoBean> mchntStageInfoBeans = new ArrayList<>();
                mchntStageInfoList.forEach(item -> convStageInfo(item, mchntStageInfoBeans));
                /* 查询结果赋值 */
                mchntProdInfoQueryResponse.setMchntStageInfoList(mchntStageInfoBeans);
            } else {
                rglog.error("法人行<{}>无商户分期信息表信息!", mchntProdInfoQueryRequest.getHeader().getInstId());
            }

            // 3. 商户费率信息表
            MchntFeeInfoMapper mchntFeeInfoMapper = new MchntFeeInfoMapperImpl();
            List<MchntFeeInfo> mchntFeeInfoList = mchntFeeInfoMapper.selectMchntFeeInfoByBaseProdCode(instId, mchntNo, baseProdCode);
            if (null != mchntFeeInfoList && !mchntFeeInfoList.isEmpty()) {
                /* 按照创建时间降序排序 */
                mchntFeeInfoList = mchntFeeInfoList.stream().sorted(Comparator.comparing(MchntFeeInfo::getCreateTime)).collect(Collectors.toList());
                Collections.reverse(mchntFeeInfoList);
                List<MchntFeeInfoBean> mchntFeeInfoBeans = new ArrayList<>();
                mchntFeeInfoList.forEach(item -> convFeeInfo(item, mchntFeeInfoBeans));
                /* 查询结果赋值 */
                mchntProdInfoQueryResponse.setMchntFeeInfoList(mchntFeeInfoBeans);
            } else {
                rglog.error("法人行<{}>无商户费率信息表信息!", mchntProdInfoQueryRequest.getHeader().getInstId());
            }

            // 4. 商户业务权限控制表
            MchntAuthCtrlMapper mchntAuthCtrlMapper = new MchntAuthCtrlMapperImpl();
            List<MchntAuthCtrl> mchntAuthCtrlList = mchntAuthCtrlMapper.selectMchntAuthCtrlInfoByBizProdCode(instId, mchntNo, baseProdCode);//todo 需确认
            if (null != mchntAuthCtrlList && !mchntAuthCtrlList.isEmpty()) {
                /* 按照创建时间降序排序 */
                mchntAuthCtrlList = mchntAuthCtrlList.stream().sorted(Comparator.comparing(MchntAuthCtrl::getCreateTime)).collect(Collectors.toList());
                Collections.reverse(mchntAuthCtrlList);
                List<MchntAuthCtrlInfoBean> mchntAuthCtrlInfoBeans = new ArrayList<>();
                mchntAuthCtrlList.forEach(item -> convAuthCtrlInfo(item, mchntAuthCtrlInfoBeans));
                /* 查询结果赋值 */
                mchntProdInfoQueryResponse.setMchntAuthCtrlInfoList(mchntAuthCtrlInfoBeans);
            } else {
                rglog.error("法人行<{}>无商户业务权限控制表信息!", mchntProdInfoQueryRequest.getHeader().getInstId());
            }

            WechatMchntInfoMapper wechatMchntInfoMapper = new WechatMchntInfoMapperImpl();
            WechatMchntInfo wechatMchntInfo = wechatMchntInfoMapper.selectWechatMchntInfoByPrimaryKey(instId, mchntNo);
            if (null != wechatMchntInfo) {
                mchntProdInfoQueryResponse.setWechatAppid(wechatMchntInfo.getAppId());
                mchntProdInfoQueryResponse.setWechatAppidKey(wechatMchntInfo.getAppSecretKey());
                mchntProdInfoQueryResponse.setWechatMiniAppid(wechatMchntInfo.getMiniAppId());
                mchntProdInfoQueryResponse.setWechatMiniAppidKey(wechatMchntInfo.getMiniSecretKey());
                mchntProdInfoQueryResponse.setWechatSelfEntryFlag(wechatMchntInfo.getIndependentEntryFlag());
            }

            CupsMchntInfoMapper cupsMchntInfoMapper = new CupsMchntInfoMapperImpl();
            CupsMchntInfo cupsMchntInfo = cupsMchntInfoMapper.selectCupsMchntInfoByPrimaryKey(instId, mchntNo);
            if (null != cupsMchntInfo) {
                mchntProdInfoQueryResponse.setCupsChannelMchntNo(cupsMchntInfo.getCupsChannelMchntNo());
            }


            /* 按照接口转换基础产品信息并响应给请求方 */
            bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
            bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
            bizResponse.setResult(mchntProdInfoQueryResponse);
        } else {
            rglog.error("商户号<{}>无商户产品信息!", mchntProdInfoQueryResponse.getMchntNo());
            bizResponse.setRespCode(RespCodeEnum.QUERY_DATA_IS_NULL.getRespCode());
            bizResponse.setRespDesc(RespCodeEnum.QUERY_DATA_IS_NULL.getRespDesc());
            bizResponse.setResult(mchntProdInfoQueryResponse);
        }
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        MchntProdInfoQueryResponse mchntProdInfoQueryResponse = (MchntProdInfoQueryResponse) bizResponse.getResult();
        List<MchntAuthCtrlInfoBean> mchntAuthCtrlInfoList = mchntProdInfoQueryResponse.getMchntAuthCtrlInfoList();
        /**
         * 银行卡支付-快捷支付：
         * 1、本行卡快捷支付(P01PM004 00)、新卡支付(本行卡)(P01PM001 00)、银行卡首次签约并支付(本行卡)(P01PM011 00)，后两个产品隐藏，并且增加与第一个产品的关联关系，即选择本行卡快捷支付时，后两个产品同步开通。
         * 2、银联无跳转支付(P01PM004 01)、银联无跳转签约并支付(P01PM013 00)、银联无跳转首次签约并支付(P01PM013 01)，参照第一条处理
         * 3、银联无卡快捷支付(P01PM004 02)、新卡支付(银联无卡快捷)(P01PM001 01)、银行卡首次签约并支付(银联无卡快捷)(P01PM011 01)，参照第一条处理
         * 【前台修改，后台无需处理】4、开通本行个人网关支付(P01PM007 00)、本行企业网关支付(P01PM007 01) ，默认开通本行网银支付API(P01CP241 00) ；
         * 本行个人网关支付退款(P04PM007 00)，本行企业网关支付退款(P04PM007 01) ，默认开通本行网银支付退款API(P04CP241 00)  ；
         * 本行网银支付API(P04PM007 00)、本行网银支付退款API(P04CP241 00)可独立开通
         * 5、收银台微信公众号支付(P01PM002 00)，默认开通 微信公众号支付API(P01CP501 00) ；收银台微信小程序支付(P01PM002 01) ，默认开通微信小程序支付API(P01CP502 00)；微信公众号支付API(P01CP501 00)、微信小程序支付API(P01CP502 00)均隐藏
         */
        if (!CollectionUtils.isEmpty(mchntAuthCtrlInfoList)) {
            Iterator iterator = mchntAuthCtrlInfoList.iterator();
            while (iterator.hasNext()) {
                MchntAuthCtrlInfoBean item = (MchntAuthCtrlInfoBean) iterator.next();
                ProdAuthCtrlEnum prodAuthCtrlEnum = ProdAuthCtrlEnum.getProdEnumByTxnNumBizType(item.getTxnNum(), item.getBizType());
                if (null == prodAuthCtrlEnum || prodAuthCtrlEnum.isShowFlag()) {
                    //为空或展示的数据跳过
                    continue;
                }
                //隐藏的数据，不返回给前台
                iterator.remove();
            }
        }
        ConvertUtil.convertInput(mchntProdInfoQueryResponse);
    }

    /**
     * 将数据库表结构对象转换成接口对象
     *
     * @param mchntStageInfo      数据库表结构对象
     * @param mchntStageInfoBeans 接口对象
     */
    private void convStageInfo(MchntStageInfo mchntStageInfo, List<MchntStageInfoBean> mchntStageInfoBeans) {
        if (AppParamConstant.YES.equals(mchntStageInfo.getRecordStatus())) {
            MchntStageInfoBean mchntStageInfoBean = new MchntStageInfoBean();
            BeanUtil.beanCopy(mchntStageInfo, mchntStageInfoBean);
            mchntStageInfoBeans.add(mchntStageInfoBean);
        }
    }

    /**
     * 将数据库表结构对象转换成接口对象
     *
     * @param mchntFeeInfo      数据库表结构对象
     * @param mchntFeeInfoBeans 接口对象
     */
    private void convFeeInfo(MchntFeeInfo mchntFeeInfo, List<MchntFeeInfoBean> mchntFeeInfoBeans) {
        if (AppParamConstant.YES.equals(mchntFeeInfo.getRecordStatus())) {
            MchntFeeInfoBean mchntFeeInfoBean = new MchntFeeInfoBean();
            BeanUtil.beanCopy(mchntFeeInfo, mchntFeeInfoBean);
            mchntFeeInfoBeans.add(mchntFeeInfoBean);
        }
    }

    /**
     * 将数据库表结构对象转换成接口对象
     *
     * @param mchntAuthCtrl          数据库表结构对象
     * @param mchntAuthCtrlInfoBeans 接口对象
     */
    private void convAuthCtrlInfo(MchntAuthCtrl mchntAuthCtrl, List<MchntAuthCtrlInfoBean> mchntAuthCtrlInfoBeans) {
        if (AppParamConstant.YES.equals(mchntAuthCtrl.getSupportFlag())) {
            //只展示生效的数据
            MchntAuthCtrlInfoBean mchntAuthCtrlInfoBean = new MchntAuthCtrlInfoBean();
            BeanUtil.beanCopy(mchntAuthCtrl, mchntAuthCtrlInfoBean);
            mchntAuthCtrlInfoBean.setBaseProdCode(mchntAuthCtrl.getBizProdCode());
            mchntAuthCtrlInfoBeans.add(mchntAuthCtrlInfoBean);
        }
    }
}
